<?php

/*
    Templights - lightweight PHP templating
    Copyright (C) 2009 Gregor Mazovec <gregor.mazovec@gmail.com>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

define('TPL_VERSION', '0.1.2');
if (!defined('TPL_BASE')) define('TPL_BASE', dirname(__FILE__).'/');

/**
 * Reads a template file - templates can be read only from path defined in
 * TPL_BASE constant.
 * 
 * @name string $file Filename of template
 * @return string Template code
 */
function tpl_read ($file) {
    if (strpos(realpath(dirname(TPL_BASE.$file)).'/', TPL_BASE) !== 0)
        throw new Exception('Loading file '.TPL_BASE.$file.' not allowed');
    if (($code = file_get_contents(TPL_BASE.$file)) === false)
        throw new Exception('Template file '.$file.' not found');
    return $code;
}

/**
 * Creates list of tokens from template code. Code is splitted by open/close tag
 * "{%" / "%}"
 *
 * @name string $code Template code
 * @return array List of tokens
 */
function tpl_token ($code) {
    return preg_split('/(\{\%)(.+)\{|\}(\%\})|\{\%\%[\s\S]*%\%\}/',
        $code, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
}

/**
 * Parses tokens and creates list of string nodes. Every block is parsed
 * seperatly.
 *
 * @name array $tokens List of tokens
 * @name array $nodelist List of string nodes (private parameter)
 * @return array List of string nodes
 */
function tpl_parse ($tokens, $nodelist = array()) {
    while (($token = array_shift($tokens)) !== null && $token != '%}')
        if ($token == '{%' && $name = trim(array_shift($tokens))) {
            if (ctype_upper($name)) $nodelist[$name] = tpl_parse(&$tokens);
            else $nodelist = tpl_parse(&$tokens, tpl_load($name));
        } else $nodelist[] = $token;
    return $nodelist;
}

/**
 * Wrapper function for loading template form file
 *
 * @name string $file Template filename
 * @return array List of string nodes
 */
function tpl_load ($file) {
    return tpl_parse(tpl_token(tpl_read($file)));
}

/**
 * Convert list of nodes into string
 *
 * @name array $tpl List of string nodes
 * @name string $b String buffer (private parameter)
 * @return string Template string appropriate for rendering
 */
function tpl_tostring ($tpl, $b = '') {
    while (($node = array_shift($tpl)) !== null)
        if (is_array($node)) $b = tpl_tostring(&$node, $b);
        else $b .= ltrim($node, "\n");
    return $b;
}

/**
 * Render template within specified context.
 *
 * @name array $tpl Template - list of nodes
 * @name array $context Template context
 * @return string Evaluated PHP code
 */
function tpl_render ($ikhbk, $dvlzj = array()) {
    extract((array)$dvlzj);
    $result = eval('unset($ikhbk, $dvlzj);
        ob_start(); ?>'.tpl_tostring($ikhbk).'<?php 
        return ob_get_clean();');
    if ($result === false)
        throw new Exception('Error while evaluating template');
    return $result;
}
